package com.bootcamp.javase2.threadpool;

/**
 * @program: day21CallableCode
 * @description: use three threads to print number alternately
 * @author: Keyu Li
 * @create: 2021-09-15 14:37
 **/

public class PrintNumAlter {
    public static void main(String[] args) {
        // 创建锁对象
        PrintNum print = new PrintNum();
        // 本次测试共3个线程，标识符是：0，1，2
        MyThread.setThreadNum(3);
        new Thread(new MyThread(print, 0), "thread 0").start();
        new Thread(new MyThread(print, 1), "thread 1").start();
        new Thread(new MyThread(print, 2), "thread 2").start();
    }
}

class MyThread implements Runnable {
    // 定义每个线程每次打印个数
    static final int LOOP = 5;
    // 设置打印终点
    static final int END_POINT = 75;
    // 定义打印的线程数，可通过静态方法设置
    static int threadNum = 3;
    public static void setThreadNum(int threadNum) {
        MyThread.threadNum = threadNum;
    }

    // 锁对象，及自身标识符 flagThread
    PrintNum print;
    int flagThread;

    public MyThread(PrintNum print, int flagThread) {
        this.print = print;
        this.flagThread = flagThread;

    }

    @Override
    public void run() {
        while (true) {
            synchronized (print) {
                // 每个线程有自己独一无二的 flag，锁对象同样也有flag，在每个线程打印后+1
                if (flagThread == print.flag) {
                    // 调用锁对象方法打印
                    printOutNum(LOOP);
                    // 设置锁对象 flag+1，对线程数量求余，得到下次打印的线程
                    print.flag = (print.flag + 1) % threadNum;
                    print.notifyAll();
                }
                try {
                    print.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void printOutNum(int loop) {
        for (int i = 0; i < loop && print.num <= END_POINT; i++) {
            System.out.println(Thread.currentThread().getName() + " ---- " + print.num);
            print.num++;
        }
    }
}

class PrintNum {

    int num = 0;
    int flag = 0;

}